package nodes;

import java.util.Queue;
import nodes.binary.AssignNode;
import model.Model;

/**
 * Used when a variable is initialized or set equal to some value
 * 
 * @author Andrew Patterson
 */
public class VariableNode extends AbstractNode
{
    private static final int DEFAULT_RETURN_VALUE = 0;

    /**
     * Construct a variable mapping to a value
     * 
     * @param variable name
     * @param value that the variable maps to
     */
    public VariableNode (String variableName, AbstractNode value, Model model)
    {
        super(model);
        myName = variableName;
        
        if(value != null)
        myModel.putVariable(myName, value);
    }
       
    /**
     * Construct a variable without a mapping
     * 
     * @param variable name
     */
    public VariableNode (String variable, Model model)
    {
        this(variable, null, model);
    }
    
    @Override
    public AbstractNode buildTree (Queue<AbstractNode> outputQueue)
    {
        if(outputQueue.peek() instanceof AssignNode)
        {
            outputQueue.poll();
            setValue(outputQueue.poll().buildTree(outputQueue));
        }
        return this;
    }

    /**
     * Looks up this variable's value in the model's map
     * If not value has been assigned, return 
     */
    public AbstractNode evaluate ()
    {
        AbstractNode value = myModel.getVariableMap().get(myName);
        if (value == null) return new ConstantNode(DEFAULT_RETURN_VALUE);
        else
        {
            return new ConstantNode(value.evaluate().getValue());
        }
    }


    public void setValue (AbstractNode value)
    {
        myModel.putVariable(myName, value);
    }


    public String getVariableName ()
    {
        return myName;
    }
}
